package com.syaccp.service.impl;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.syaccp.exception.CrmebException;
import com.syaccp.mapper.SysMenuMapper;
import com.syaccp.model.SysMenu;
import com.syaccp.request.SysMenuRequest;
import com.syaccp.request.SysMenuSearchRequest;
import com.syaccp.service.SysMenuService;
import com.syaccp.utils.RedisUtil;
import com.syaccp.vo.MenuCheckTree;
import com.syaccp.vo.MenuCheckVo;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * <p>
 * 系统菜单表 服务实现类
 * </p>
 *
 * @author lixin
 * @since 2023-07-02
 */
@Service("sysMenuService")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

	private static final String CACHE_LIST_KEY = "menuList";

	@Autowired
	private SysMenuMapper sysMenuMapper;

	@Autowired
	private RedisUtil redisUtil;

	@Override
	public List<SysMenu> getAdminList(SysMenuSearchRequest request) {
		LambdaQueryWrapper<SysMenu> lqw = Wrappers.lambdaQuery();
		if (StrUtil.isNotEmpty(request.getName())) {
			lqw.like(SysMenu::getName, request.getName());
		}
		if (StrUtil.isNotEmpty(request.getMenuType())) {
			lqw.eq(SysMenu::getMenuType, request.getMenuType());
		}
		lqw.eq(SysMenu::getDelFlag, 0);
		lqw.orderByDesc(SysMenu::getSort);
		lqw.orderByAsc(SysMenu::getId);
		return sysMenuMapper.selectList(lqw);
	}

	@Override
	public Boolean add(SysMenuRequest request) {

		if (request.getMenuType().equals("C") && StrUtil.isEmpty(request.getComponent())) {
			throw new CrmebException("菜单类型的组件路径不能为空");
		}
		if (request.getMenuType().equals("A") && StrUtil.isEmpty(request.getPerms())) {
			throw new CrmebException("按钮类型的权限表示不能为空");
		}
		SysMenu sysMenu = new SysMenu();
		request.setId(null);
		BeanUtils.copyProperties(request, sysMenu);
		boolean save = save(sysMenu);
		if (save) {
			redisUtil.delete(CACHE_LIST_KEY);
		}
		return save;
	}

	@Override
	public Boolean deleteById(Integer id) {

		SysMenu sysMenu = getInfoById(id);
		sysMenu.setDelFlag(2);
		if (sysMenu.getMenuType().equals("A")) {
			boolean update = updateById(sysMenu);
			if (update) {
				redisUtil.delete(CACHE_LIST_KEY);
			}
			return update;
		}
		List<SysMenu> childList = findAllChildListByPid(id);
		if (CollUtil.isEmpty(childList)) {
			boolean update = updateById(sysMenu);
			if (update) {
				redisUtil.delete(CACHE_LIST_KEY);
			}
			return update;
		}
		childList.forEach(e -> e.setDelFlag(2));
		childList.add(sysMenu);
		boolean updateBatch = updateBatchById(childList);
		if (updateBatch) {
			redisUtil.delete(CACHE_LIST_KEY);
		}
		return updateBatch;
	}

	@Override
	public Boolean edit(SysMenuRequest request) {

		if (ObjectUtil.isNull(request.getId())) {
			throw new CrmebException("系统菜单id不能为空");
		}
		if (request.getMenuType().equals("C") && StrUtil.isEmpty(request.getComponent())) {
			throw new CrmebException("菜单类型的组件路径不能为空");
		}
		if (request.getMenuType().equals("A") && StrUtil.isEmpty(request.getPerms())) {
			throw new CrmebException("按钮类型的权限表示不能为空");
		}
		SysMenu sysMenu = new SysMenu();
		BeanUtils.copyProperties(request, sysMenu);
		boolean update = updateById(sysMenu);
		if (update) {
			redisUtil.delete(CACHE_LIST_KEY);
		}
		return update;
	}

	@Override
	public SysMenu getInfo(Integer id) {

		SysMenu sysMenu = getInfoById(id);
		sysMenu.setDelFlag(null);
		sysMenu.setCreateTime(null);
		sysMenu.setUpdateTime(null);
		return sysMenu;
	}

	@Override
	public Boolean updateShowStatus(Integer id) {

		SysMenu sysMenu = getInfoById(id);
		
		Integer status = sysMenu.getStatus();
		if (status.equals(0)) {
			sysMenu.setStatus(1);
		} else {
			sysMenu.setStatus(0);

		}

		boolean update = updateById(sysMenu);
		if (update) {
			redisUtil.delete(CACHE_LIST_KEY);
		}
		return update;
	}

	@Override
	public List<MenuCheckVo> getCacheTree() {

		  List<SysMenu> menuList = getCacheList();
	        List<MenuCheckVo> voList = menuList.stream().map(e -> {
	            MenuCheckVo menuCheckVo = new MenuCheckVo();
	            BeanUtils.copyProperties(e, menuCheckVo);
	            return menuCheckVo;
	        }).collect(Collectors.toList());
	        MenuCheckTree menuTree = new MenuCheckTree(voList);
	        return menuTree.buildTree();
	}

	/**
	 * 根据菜单id获取所有下级对象
	 * 
	 * @param pid 菜单id
	 * @return List<SystemMenu>
	 */
	private List<SysMenu> findAllChildListByPid(Integer pid) {
		LambdaQueryWrapper<SysMenu> lqw = Wrappers.lambdaQuery();
		lqw.eq(SysMenu::getPid, pid);
		lqw.eq(SysMenu::getDelFlag, 0);
		return sysMenuMapper.selectList(lqw);
	}

	/**
	 * 获取详细信息
	 * 
	 * @param id 菜单id
	 * @return SystemMenu
	 */
	private SysMenu getInfoById(Integer id) {
		SysMenu sysMenu = getById(id);
		if (ObjectUtil.isNull(sysMenu) || sysMenu.getDelFlag().equals(2)) {
			throw new CrmebException("系统菜单不存在");
		}
		return sysMenu;
	}

	@Override
	public List<String> findPermissionByUserId(Integer userId) {
		List<String> list = sysMenuMapper.findPermissionByUserId(userId);
		return list;
	}

	@Override
	public List<String> getAllPermissions() {
		List<String> list = sysMenuMapper.getAllPermissions();
		return list;
	}

	@Override
	public List<SysMenu> findAllCatalogue() {
		// select *From sys_menu where menu_type!='A' and status=1 and del_flag=0
		LambdaQueryWrapper<SysMenu> lqw = Wrappers.lambdaQuery();
		lqw.eq(SysMenu::getStatus, 1);

		lqw.eq(SysMenu::getDelFlag, 0);
		lqw.ne(SysMenu::getMenuType, "A");

		return sysMenuMapper.selectList(lqw);

	}

	@Override
	public List<SysMenu> getMenusByUserId(Integer userId) {

		return sysMenuMapper.getMenusByUserId(userId);
	}

	/**
	 * 获取菜单缓存列表
	 */
	@Override
	public List<SysMenu> getCacheList() {
		if (redisUtil.exists(CACHE_LIST_KEY)) {
			return redisUtil.get(CACHE_LIST_KEY);
		}
		LambdaQueryWrapper<SysMenu> lqw = Wrappers.lambdaQuery();
		lqw.eq(SysMenu::getDelFlag, 0);
		lqw.eq(SysMenu::getStatus, 1);
		List<SysMenu> sysMenuList = sysMenuMapper.selectList(lqw);
		redisUtil.set(CACHE_LIST_KEY, sysMenuList);
		return sysMenuList;
	}

}
